package org.robot.scm.platform.server.handler;

import static org.robot.scm.platform.server.LockKey.LAST_KEY;
import static org.robot.scm.platform.server.LockKey.LOCK_KEY;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.robot.scm.infra.LocalCacheHelper;
import org.robot.scm.infra.RedisCacheHelper;
import org.robot.scm.platform.registry.TelegramRegistry;
import org.robot.scm.utils.RandomUtil;

@Slf4j
@NoArgsConstructor
public class UploadHandler extends BaseHandler implements HttpHandler {

    @Override
    public String getUri() {
        return "/upload";
    }

    @Override
    public void handle(HttpExchange exchange) throws IOException {
        // 并发校验
        String locker = RedisCacheHelper.get(LOCK_KEY);
        if (StringUtils.isNotBlank(locker)) {
            sendSuccessResponse(exchange, "有任务正在执行中");
            return;
        }

        if (!exchange.getRequestMethod().equalsIgnoreCase("POST")) {
            sendFailureResponse(exchange, "请求非法");
            return;
        }

        // sqllike清理、本地日志缓存清理
        RedisCacheHelper.remove(LAST_KEY);
        TelegramRegistry.clearSqlLike();
        LocalCacheHelper.clear();

        String fileKey = RandomUtil.uuidNoLine();
        File targetFile = new File("assets/telegram/" + fileKey + ".sql");
        StringBuilder builder = new StringBuilder();
        try (OutputStream out = Files.newOutputStream(targetFile.toPath()); BufferedReader reader = new BufferedReader(new InputStreamReader(exchange.getRequestBody(), StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String fileName = handleFileName(fileKey, line);

                if (StringUtils.isNotBlank(fileName)) {
                    builder.append(System.lineSeparator())
                            .append("##### ").append(fileName).append(" #####")
                            .append(System.lineSeparator())
                            .append(System.lineSeparator());
                }

                if (!lineValid(line)) {
                    continue;
                }

                builder.append(line).append(System.lineSeparator());
            }
            out.write(builder.toString().trim().getBytes(StandardCharsets.UTF_8));
            sendSuccessResponse(exchange, fileKey);
        } catch (IOException e) {
            sendFailureResponse(exchange, e.getMessage());
        }
    }

    private String handleFileName(String fileKey, String line) {
        if (!StringUtils.contains(line, "Content-Disposition") || !StringUtils.contains(line, "filename=")) {
            return StringUtils.EMPTY;
        }
        String regex = "filename=\"([^\"]+)\"";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(line);
        // 21,600 = 6小时
        if (matcher.find()) {
            RedisCacheHelper.put(fileKey, matcher.group(1), 21600);
            return matcher.group(1);
        }
        return StringUtils.EMPTY;
    }

    private boolean lineValid(String line) {
        return !StringUtils.startsWith(line, "------WebKitFormBoundary") &&
                !StringUtils.startsWith(line, "Content-Disposition:") &&
                !StringUtils.startsWith(line, "Content-Type:") &&
                StringUtils.isNotBlank(line);
    }
}
